package com.android.accessibility.function;

import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;

import android.accessibilityservice.AccessibilityService;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
import android.text.TextUtils;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;

import com.android.accessibility.NickInfo;
import com.android.accessibility.provider.DBConstant;
import com.android.accessibility.service.MyAccessibilityService;
import com.android.accessibility.stat.StatManager;
import com.android.accessibility.utils.Log;

public class AudoSendMsgAccessibility extends Accessibility {

    private static final int MSG_PERFORMCLICK = 1;
    private static final int MSG_PERFORMPASTE = 2;
    private static final int MSG_PERFORMBACK = 3;
    private static final int MSG_PERFORM_SENDMSG = 4;
    private static final boolean ALLOW_CLICK = true;
    private static final CharSequence LauncherUI = "com.tencent.mm.ui.LauncherUI";
    private static final CharSequence ContactInfoUI = "com.tencent.mm.plugin.profile.ui.ContactInfoUI";
    private static final CharSequence ChattingUI = "com.tencent.mm.ui.chatting.ChattingUI";

    private Queue<ContactItem> mItemList;
    private Handler mHandler = null;
    private List<NickInfo> mWhiteList = null;

    public AudoSendMsgAccessibility(AccessibilityService service) {
        super(service);
        mWhiteList = StatManager.get(getService()).getWhiteList();
        mHandler = new Handler() {

            @Override
            public void handleMessage(Message msg) {
                switch(msg.what) {
                case MSG_PERFORMCLICK:
                    performClick();
                    break;
                case MSG_PERFORMPASTE:
                    paste();
                    break;
                case MSG_PERFORMBACK:
                    clickBack();
                    break;
                case MSG_PERFORM_SENDMSG:
                    clickSendMsg();
                    break;
                }
            }
        };
    }

    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        int eventType = event.getEventType();
        // Log.d(Log.TAG, "mClassName : " + mClassName);
        if (eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
            // Log.d(Log.TAG, "AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED");
            if (LauncherUI.equals(mClassName)) {
                handleClick();
            } else if (ContactInfoUI.equals(mClassName)) {
                List<AccessibilityNodeInfo> list = Helper.findClickableNodeListByText(getService(), "查看历史消息");
                if (list != null && list.size() > 0) {
                    handleClickBack();
                } else {
                    handleClickSensMsg();
                }
            } else if (ChattingUI.equals(mClassName)) {
                handlePaste();
                handleClickBack();
            }
        } else if (eventType == AccessibilityEvent.TYPE_VIEW_SCROLLED) {
            // Log.d(Log.TAG, "AccessibilityEvent.TYPE_VIEW_SCROLLED");
            if (TextUtils.isEmpty(mClassName)) {
                mClassName = MyAccessibilityService.sLastClassName;
            }
            if (LauncherUI.equals(mClassName)
                    && "android.widget.ListView".equals(event.getClassName())) {
                init();
                handleClick();
            }
        } else if (eventType == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED) {
            // Log.d(Log.TAG, "AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED");
            if (LauncherUI.equals(mClassName)) {
                if (mItemList == null) {
                    init();
                }
                handleClick();
            }
        }
    }

    private void init() {
        if (mItemList == null) {
            mItemList = new LinkedBlockingQueue<ContactItem>();
        }
        fillList();
    }

    private void clean() {
        mItemList = null;
    }

    private void fillList() {
        List<ContactItem> list = getListItem();
        addAll(list);
    }

    private void addAll(List<ContactItem> list) {
        if (mItemList == null || list == null) {
            return;
        }
        for (ContactItem i : list) {
            mItemList.add(i);
        }
    }

    private void handleClick() {
        if (!mHandler.hasMessages(MSG_PERFORMCLICK)) {
            mHandler.sendEmptyMessageDelayed(MSG_PERFORMCLICK, 500);
        }
    }

    private void performClick() {
        if (!ALLOW_CLICK) {
            return;
        }
        if (mItemList == null) {
            return;
        }
        Log.d(Log.TAG, "mItemList.size() : " + mItemList.size());
        if (mItemList.size() > 0) {
            boolean allowSend = false;
            do {
                ContactItem item = mItemList.poll();
                if (item != null) {
                    allowSend = allowSend(item);
                    Log.d(Log.TAG, "name : " + item.nickName + " , allowSend : "
                            + allowSend);
                    if (allowSend) {
                        if (item.nodeInfo != null) {
                            item.nodeInfo
                                    .performAction(AccessibilityNodeInfo.ACTION_CLICK);
                            StatManager.get(getService()).insertData(
                                    item.nickName, System.currentTimeMillis(),
                                    DBConstant.TYPE_SENT);
                            break;
                        }
                    }
                } else {
                    checkScroll();
                    break;
                }
            } while (!allowSend);
        } else {
            checkScroll();
        }
    }

    private void handleClickSensMsg() {
        if (!mHandler.hasMessages(MSG_PERFORM_SENDMSG)) {
            mHandler.sendEmptyMessageDelayed(MSG_PERFORM_SENDMSG, 1000);
        }
    }

    private void clickSendMsg() {
        Helper.findAndPerformAction(getService(), "发消息");
    }

    private void copy(CharSequence text) {
        ClipboardManager clipboard = (ClipboardManager) getService()
                .getSystemService(Context.CLIPBOARD_SERVICE);
        ClipData clip = ClipData.newPlainText("label", text);
        clipboard.setPrimaryClip(clip);
    }

    private boolean allowSend(ContactItem item) {
        boolean isSent = isSent(item);
        if (mWhiteList != null && mWhiteList.size() > 0) {
            boolean isWhite = isWhite(item);
            if (isWhite && !isSent) {
                return true;
            }
            return false;
        }
        boolean isBlack = isBlack(item);
        return (!isBlack && !isSent);
    }

    private boolean isSent(ContactItem item) {
        if (item == null) {
            return true;
        }
        return StatManager.get(getService()).isSent(item.nickName);
    }

    private boolean isBlack(ContactItem item) {
        if (item == null) {
            return true;
        }
        return StatManager.get(getService()).isBlack(item.nickName);
    }

    private boolean isWhite(ContactItem item) {
        if (item == null) {
            return true;
        }
        return StatManager.get(getService()).isWhite(item.nickName);
    }

    private void checkScroll() {
        if (mItemList != null && mItemList.size() <= 0) {
            AccessibilityNodeInfo listNodeInfo = getContactNode();
            Log.d(Log.TAG, "ACTION_SCROLL_FORWARD");
            if (listNodeInfo != null) {
                listNodeInfo
                        .performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
            }
        }
    }

    private void handlePaste() {
        if (!mHandler.hasMessages(MSG_PERFORMPASTE)) {
            mHandler.sendEmptyMessageDelayed(MSG_PERFORMPASTE, 1000);
        }
    }
    private void paste() {
        AccessibilityNodeInfo nodeInfo = getService().getRootInActiveWindow();
        AccessibilityNodeInfo info = Helper.findViewNodeInfo(nodeInfo,
                "android.widget.EditText");
        if (info != null) {
            AccessibilityNodeInfoCompat compat = new AccessibilityNodeInfoCompat(info);
            String content = PreferenceManager.getDefaultSharedPreferences(
                    getService()).getString("content", "你好");
            Log.d(Log.TAG, "发送内容 ： " + content);
            copy(content);
            info.performAction(AccessibilityNodeInfo.ACTION_FOCUS);
            compat.performAction(AccessibilityNodeInfoCompat.ACTION_PASTE);
            Helper.findAndPerformAction(getService(), "发送");
        }
    }

    private AccessibilityNodeInfo getContactNode() {
        AccessibilityNodeInfo viewPagerInfo = Helper.findViewNodeInfo(
                getService().getRootInActiveWindow(),
                "android.support.v4.view.ViewPager");
        if (viewPagerInfo == null) {
            return null;
        }
        AccessibilityNodeInfo listViewInfo = Helper.findViewNodeInfo(
                viewPagerInfo, "android.widget.ListView", 1);
        return listViewInfo;
    }

    private List<ContactItem> getListItem() {
        AccessibilityNodeInfo contactNode = getContactNode();
        List<ContactItem> list = null;
        if (contactNode != null) {
            list = new ArrayList<ContactItem>();
            ContactItem item = null;
            AccessibilityNodeInfo info = null;
            int count = contactNode.getChildCount();
            for (int index = 0; index < count; index++) {
                info = contactNode.getChild(index);
                CharSequence nickName = getNickName(info);
                if (!TextUtils.isEmpty(nickName)) {
                    item = new ContactItem();
                    item.id = String.valueOf(info.hashCode());
                    item.nickName = nickName;
                    item.nodeInfo = info;
                    list.add(item);
                    // Log.d(Log.TAG, "nickName : " + nickName);
                }
            }
        }
        return list;
    }

    private CharSequence getNickName(AccessibilityNodeInfo childNode) {
        if (childNode != null) {
            int count = childNode.getChildCount();
            AccessibilityNodeInfo info = null;
            for (int index = 0; index < count; index++) {
                info = childNode.getChild(index);
                if (info != null
                        && "android.view.View".equals(info.getClassName())) {
                    return info.getText();
                }
            }
        }
        return null;
    }

    private void handleClickBack() {
        if (!mHandler.hasMessages(MSG_PERFORMBACK)) {
            mHandler.sendEmptyMessageDelayed(MSG_PERFORMBACK, 2000);
        }
    }

    private void clickBack() {
        if (!ALLOW_CLICK) {
            return;
        }
        Log.d(Log.TAG, "");
        getService().performGlobalAction(
                AccessibilityService.GLOBAL_ACTION_BACK);
    }

    class ContactItem {
        public CharSequence id;
        public CharSequence nickName;
        public AccessibilityNodeInfo nodeInfo;

        @Override
        public String toString() {
            String out = "";
            out += "\nid       : " + id + "\n";
            out += "nickName : " + nickName + "\n";
            return out;
        }
    }

    @Override
    public void start() {
        Log.d(Log.TAG, "");
        init();
        handleClick();
    }

    @Override
    public void stop() {
        Log.d(Log.TAG, "");
        clean();
    }
}
